package index;

public class CalculatorOfWorkingWithDisk {
	private static final int COST_POSITIONING = 10;
	private static final double COST_SLEW_BLOCKS = 60.0 / (7200 * 512);
	private static int amountOfPositioningDriveHead = 0;
	private static int amountOfSlewBlocks = 0;
	private static int callFlush = 0;
	private static int callPull = 0;
	private static int callAllocateIteratingSlot = 0;
	private static int callAllocateOutputSlot_UseLastBlock = 0;
	private static int callAllocateOutputSlot = 0;
	private static int callReleaseInOutputSlot = 0;
	private static int callReleaseIteratingSlot = 0;
	private static int minBufferCount = Integer.MAX_VALUE;
	private static int maxBufferCount = 0;

	public static void reset() {
		amountOfPositioningDriveHead = 0;
		amountOfSlewBlocks = 0;
		callFlush = 0;
		callPull = 0;
		callAllocateIteratingSlot = 0;
		callAllocateOutputSlot_UseLastBlock = 0;
		callAllocateOutputSlot = 0;
		callReleaseInOutputSlot = 0;
		callReleaseIteratingSlot = 0;
		minBufferCount = Integer.MAX_VALUE;
		maxBufferCount = 0;
	}


	public static void callFlush() {
		amountOfPositioningDriveHead++;
		amountOfSlewBlocks++;
		callFlush++;
	}


	public static void callPull(int bufferCount) {
		amountOfPositioningDriveHead++;
		amountOfSlewBlocks += bufferCount;
		if(bufferCount < minBufferCount ){
			minBufferCount = bufferCount;
		}
		if(bufferCount > maxBufferCount ){
			maxBufferCount = bufferCount;
		}
		callPull++;
	}

	public static int compute() {
		printCalls();
		return amountOfPositioningDriveHead * COST_POSITIONING
				+ (int) (amountOfSlewBlocks * COST_SLEW_BLOCKS);
	}

	private static void printCalls() {
		System.out.println("\nLIST CALLS:");
		System.out.println("callAllocateIteratingSlot = "
				+ callAllocateIteratingSlot);
		System.out.println("callPull = " + callPull);
		System.out.println("callReleaseIteratingSlot = "
				+ callReleaseIteratingSlot);
		System.out.println();
		System.out
				.println("callAllocateOutputSlot = " + callAllocateOutputSlot);
		System.out.println("callAllocateOutputSlot_UseLastBlock = "
				+ callAllocateOutputSlot_UseLastBlock);
		System.out.println("callFlush = " + callFlush);
		System.out.println("callReleaseInOutputSlot = "
				+ callReleaseInOutputSlot);
		System.out.println();
		System.out
				.println("amountOfPositioningDriveHead = "
						+ amountOfPositioningDriveHead + "( *"
						+ COST_POSITIONING + ")");
		System.out.println("amountOfSlewBlocks = " + amountOfSlewBlocks
				+ " ( *" + COST_SLEW_BLOCKS + ")");
		System.out.println();
		System.out.println("minBufferCount = "+ minBufferCount + " maxBufferCount = "+ maxBufferCount);
	}

	public static void callAllocateIteratingSlot() {
		callAllocateIteratingSlot++;
	}

	public static void callAllocateOutputSlot(boolean useLastBlock) {
		if (useLastBlock) {
			callAllocateOutputSlot_UseLastBlock++;
		} else {
			callAllocateOutputSlot++;
		}

	}

	public static void callReleaseInOutputSlot() {
		callReleaseInOutputSlot++;
	}

	public static void callReleaseIteratingSlot() {
		callReleaseIteratingSlot++;
	}

    public static String buildReport() {
        return new StringBuilder("#seeks = ").append(amountOfPositioningDriveHead).append("\n")
            .append("#sequential scans = ").append(amountOfSlewBlocks).append("\n")
            .append("total cost = ").append(compute()).toString();
    }
}
